<template>
	<view class="uni-uploader-bd">
		<view class="uni-uploader-files">
			<block v-for="(item, index) in upload_before_list" :key="index">
				<view class="uni-uploader-file" @click="previewImage(index)">
					<image class="uni-uploader-img" :style="upload_img_wh" :src="item.path" mode="aspectFill" />
					<view class="uni-img-removeicon right" @click.stop="removeImage(index)" v-show="upimg_move">×</view>
				</view>
			</block>
			<view v-show="upload_len < upload_count" hover-class="uni-uploader-hover" class="uni-uploader-inputbox" @click="chooseImage"
			 :style="upload_img_wh">
				<text class="uni-uploader-add"></text>
			</view>
		</view>
	</view>
</template>

<script>
	import * as config from '@/config/index.js'
	let baseUrl = config.def().baseUrl
	export default {
		data() {
			return {
				upload_len: 0,
				upload_cache: [],
				upload_cache_list: [],
				upload_before_list: []
			}
		},
		name: 'uni-upimg',
		props: {
			// 服务器url
			url: {
				type: String,
				default: baseUrl + '/maoyi/oss/photoupload'
			},
			// 上传样式宽高
			upload_img_wh: {
				type: String,
				default: 'width:120upx; height:120upx;'
			},
			// 上传数量
			upload_count: {
				type: [Number, String],
				default: 9
			},
			// 是否自动上传? 可以先用变量为false然后再改为true即为手动上传
			upload_auto: {
				type: Boolean,
				default: true
			},
			// 是否显示删除
			upimg_move: {
				type: Boolean,
				default: true
			},
			// 服务器预览图片
			upimg_preview: {
				type: Array,
				default: () => {
					return [];
				}
			},
			// 服务器返回预览(看服务器卡顿情况设定)
			upimg_delaytime: {
				type: [Number, String],
				default: 300
			},
			// 请求头信息
			header: {
				type: Object,
				default: () => {
					return {}
				}
			}
		},
		async created() {
			setTimeout(() => {
				this.upload_before_list = this.upload_before_list.concat(this.upimg_preview)
				this.upload_len = this.upload_before_list.length
				this.upimg_preview.map(item => {
					this.upload_cache_list.push(item.path)
				})
				this.emit()
			}, this.upimg_delaytime)
		},
		methods: {
			upImage(paths, header) {
				const promises = paths.map(path => {
					return promisify(upload)({
						url: this.url,
						path: path,
						name: 'file',
						extra: header,
						that: this
					})
				})
				uni.showLoading({
					title: `正在上传...`
				})
				Promise.all(promises).then(data => {
					uni.hideLoading()
					this.upload_cache_list.push(...data)
					this.emit()
				}).catch(res => {
					uni.hideLoading()
				})
			},
			chooseImage() {
				uni.chooseImage({
					count: this.upload_count - this.upload_before_list.length,
					sizeType: ['compressed', 'original'],
					sourceType: ['album', 'camera'],
					success: res => {
						for (let i = 0, len = res.tempFiles.length; i < len; i++) {
							res.tempFiles[i]['upload_percent'] = 0
							this.upload_before_list.push(res.tempFiles[i])
						}
						this.upload_cache = res.tempFilePaths
						this.upload()
					},
					fail: err => {
						console.log(err)
					}
				})
			},
			async upload() {
				await this.upImage(this.upload_cache, this.header)
			},
			previewImage(idx) {
				let preview = []
				for (let i = 0, len = this.upload_before_list.length; i < len; i++) {
					preview.push(this.upload_before_list[i].path)
				}
				uni.previewImage({
					current: idx,
					urls: preview
				})
			},
			removeImage(idx) {
				this.upload_before_list.splice(idx, 1)
				this.upload_cache_list.splice(idx, 1)
				this.upload_len = this.upload_before_list.length
				this.emit()
			},
			emit() {
				this.$emit('change', this.upload_cache_list)
			}
		}
	}
	const promisify = api => {
		return function(option, ...params) {
			return new Promise(function(resolve, reject) {
				api(
					Object.assign({}, option, {
						success: resolve,
						fail: reject
					}),
					...params
				)
			})
		}
	}
	const upload = option => {
		let url = option.url,
			that = option.that,
			path = option.path,
			name = option.name,
			extra = option.extra,
			success = option.success,
			progress = option.progress,
			fail = option.fail
		const uploadTask = uni.uploadFile({
			url: url,
			filePath: path,
			name: name,
			formData: extra,
			success: res => {
				let data = res.data
				// 根据自己的返回数据做相应判断,服务器返回200即代表成功请求
				if (res.statusCode == 200 && JSON.parse(res.data).code == 200) {
					data = JSON.parse(res.data).data.photos
					success && success(data)
				} else {
					fail && fail(data)
				}
			},
			fail: res => {
				console.log(res)
				fail && fail(res)
			}
		})
		uploadTask.onProgressUpdate(async res => {
			for (let i = 0, len = that.upload_before_list.length; i < len; i++) {
				that.upload_before_list[i]['upload_percent'] = await res.progress
			}
			that.upload_before_list = that.upload_before_list
			that.upload_len = that.upload_before_list.length
		})
	}
</script>

<style lang="scss">
	.uni-uploader-img {
		display: block;
		width: 120upx;
		height: 120upx;
	}

	.uni-uploader-input {
		position: absolute;
		z-index: 1;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		opacity: 0;
	}

	.uni-uploader-inputbox {
		position: relative;
		box-sizing: border-box;
		background-color: #ededed;
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		justify-content: center;
		width: 120upx;
		height: 120upx;
		margin-top: 16upx;
		margin-left: 16upx;
	}

	.uni-uploader-add {
		width: 60upx;
		height: 60upx;
		vertical-align: top;
		background: url('') no-repeat center center;
		background-size: 60upx 60upx;
	}

	.uni-img-removeicon {
		position: absolute;
		width: 30upx;
		height: 30upx;
		font-size: $base-font-sm;
		color: #fff;
		line-height: 30upx;
		z-index: 2;
		text-align: center;
		border-radius: 30upx;
		background-color: #868686;

		&.right {
			top: -10upx;
			right: -10upx;
		}
	}

	.uni-uploader-file {
		position: relative;
		margin-left: 16upx;
		margin-top: 16upx;
	}

	.uni-uploader-file-status:before {
		content: ' ';
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		background-color: rgba(0, 0, 0, 0.5);
	}

	.uni-loader-filecontent {
		position: absolute;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		color: #fff;
		z-index: 9;
	}

	.uni-uploader-bd {
		padding: 0;
		margin: 0;
		flex: 1;
	}

	.uni-uploader-files {
		display: flex;
		flex-wrap: wrap;
		margin: -16upx 0 0 -16upx;
	}

	.uni-uploader-inputbox>view {
		text-align: center;
	}

	.uni-uploader-file-status:after {
		content: ' ';
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		background-color: rgba(0, 0, 0, 0.5);
	}

	.uni-uploader-hover {
		box-shadow: 0 0 0 #e5e5e5;
		background: #e5e5e5;
	}

	/* #ifdef H5 */
	@media screen and (min-width: 750px) {
		.uni-uploader-img {
			width: 120px !important;
			height: 120px !important;
			cursor: pointer;
		}

		.uni-uploader-inputbox {
			width: 120px !important;
			height: 120px !important;
			margin-top: 16px;
			margin-left: 16px;
		}

		.uni-uploader-add {
			width: 60px;
			height: 60px;
			cursor: pointer;
			background-size: 60px 60px;
		}

		.uni-img-removeicon {
			width: 30px;
			height: 30px;
			font-size: 24px;
			line-height: 24px;
			border-radius: 30px;

			&.right {
				top: -10px;
				right: -10px;
			}
		}

		.uni-uploader-file {
			margin-left: 16px;
			margin-top: 16px;
		}

		.uni-uploader-files {
			margin: -16px 0 0 -16px;
		}
	}

	/* #endif */
</style>
